#include "dht11.h"
#include "delay.h"


//DHT11管脚初始化
void DHT11PinInit(void)
{
	RCC->APB2ENR |=0x01<<0;//AFIO时钟使能
	AFIO->MAPR &=~(0x07<<24);
	AFIO->MAPR |=(0x02<<24);//管脚重映射
	
	//DATA---PB3---开漏输出
	RCC->APB2ENR |= 0x01<<3;//端口B时钟使能
	GPIOB->CRL &=~(0x0F<<12);
	GPIOB->CRL |= (0x07<<12);
	
	DATA_H;//保证总线在空闲状态
	
	Delayms(1000);
}



//函数：读取一个字节数据
static uint8_t ReadByte(void) 
{
	uint8_t i;
	uint8_t data=0;
	
	for(i=0;i<8;i++)
	{
		while(!DATA_IN);
		Delayus(50);
//		data<<=1;//空出最低位来存放数据
//		if(DATA_IN==1)
//			data |=1;
		data =(data<<1) | DATA_IN;
		while(DATA_IN);
	}
	
	return data;
}

//函数：读取温度和湿度
uint8_t ReadDHT11(TYPE_DHT11* data)
{
	uint8_t RH_H=0,RH_L=0,Temp_H=0,Temp_L=0,Check=0;
	uint8_t timeout=0;//超时计数值
	
	//开始信号
	DATA_L;//产生开始信号
	Delayms(18);//开始信号持续时间
	DATA_H;//结束开始信号
	
	//等待应答信号
	DATA_H;//切换为读模式
	while(DATA_IN)//等待应答信号
	{
		timeout++;
		Delayus(2);
		if(timeout>=40)
			return 1;
	}
	while(!DATA_IN);//等待应答信号结束
	while(DATA_IN);//等待80us高电平结束
	//循环读取40位数据
	RH_H= ReadByte( );
	RH_L= ReadByte( );
	Temp_H= ReadByte( );
	Temp_L= ReadByte( );
	Check= ReadByte( );
	//校验数据
	if( Check!=((RH_H+RH_L+Temp_H+Temp_L)&0xFF) )
	{
		return 2;
	}
	data->humi=RH_H+1.0*RH_L/10;
	data->temp=Temp_H+1.0*Temp_L/10;
	
	return 0;
}


